package com.sdy.mvc.service.impl;

import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sdy.mvc.mapper.BaseMapper;
import com.sdy.mvc.service.BaseService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
public class BaseServiceImpl<T> extends ServiceImpl<BaseMapper<T>, T> implements BaseService<T> {
    @Autowired
    private BaseMapper<T> baseMapper;

    @Override
    public List<T> listByExample(T t) {
        Map<String, Object> map = new HashMap<>();
        Class clazz = t.getClass();
        Field[] fields = clazz.getDeclaredFields();
        String orderByField = null;
        for (Field item : fields) {
            TableField anno1 = item.getAnnotation(TableField.class);
            if (!Modifier.isStatic(item.getModifiers())) {
                if (anno1 == null || anno1.exist()) {
                    try {
                        item.setAccessible(true);
                        Object value = item.get(t);
                        if (value != null) {
                            String key = underscoreName(item.getName());
                            map.put(key, value);
                            TableId anno2 = item.getAnnotation(TableId.class);
                            if (anno2 != null) {
                                orderByField = key;
                            }
                        }
                    } catch (IllegalAccessException e) {
                        log.error("listByExample reflect error, field:{}", item.getName(), e);
                    }
                }
            }
        }
        QueryWrapper<T> qw = new QueryWrapper<>();
        for (Map.Entry<String, Object> entry : map.entrySet()) {
            qw.eq(entry.getKey(), entry.getValue());
        }
        if (orderByField != null) {
            qw.orderByDesc(orderByField);
        }
        return new ArrayList<>(list(qw));
    }

    private static String underscoreName(String camelCaseName) {
        StringBuilder result = new StringBuilder();
        if (camelCaseName != null && camelCaseName.length() > 0) {
            result.append(camelCaseName.substring(0, 1).toLowerCase());
            for (int i = 1; i < camelCaseName.length(); i++) {
                char ch = camelCaseName.charAt(i);
                if (Character.isUpperCase(ch)) {
                    result.append("_");
                    result.append(Character.toLowerCase(ch));
                } else {
                    result.append(ch);
                }
            }
        }
        return result.toString();
    }
}